/*
 * Resource.h
 *
 *	Is an abstract resource. It may be loaded at startup or when necessary.
 *
 *  Created on: Jul 28, 2013
 *      Author: zapmunk
 */
#pragma once

class Resource;

//A class for tracking loading progress
class ProgressTracker {
private:
	friend class Resource;
	uint bytes;
	uint maxbytes;
public:
	ProgressTracker(): bytes(0), maxbytes(-1) {};	//Deliberate underflow yay!
	uint getBytes() const;
	uint getMaxBytes() const;
	double getProgress() const;	//Returns the percent it's done (between 0 and 1)
};

class Resource {
public:
	enum LoadType {
		PRELOAD,	//Load ASAP, only for things necessary for a startup loading screen
		AUTOLOAD,	//Load during aforementioned loading screen
		MANUAL,		//Don't load until necessary (aka during secondary load screens)
	};
private:
	std::string name;	//Name of this resource, for debugging/error handling purposes
	const char* path;	//File path where the resource should be loaded from
	const LoadType loadtype;	//When should this resource be loaded
	char* m_data;
	int m_size;

	bool m_isLoaded;

	static const int READ_BLOCK_SIZE = 1024;
protected:
	char *const &data;	//The loaded data for this resource
						//WARNING: READ-ONLY. Different OSs prolly handle it differently if you try to write to this, but a segfault is not unlikely
	const int& size;	//The size of the data, in bytes
public:
	typedef char RESOURCE_ERROR;
	static const RESOURCE_ERROR ERROR_UNKNOWN = 0;
	static const RESOURCE_ERROR ERROR_NOT_LOADED = 1;

	Resource(const char* path, LoadType loadtype = MANUAL, std::string name = "Unnamed Resource");

	//Loads the resource from it's path into memory.
	bool load(ProgressTracker* tracker = NULL);
	//Unloads the resource from memory
	void unload();

	bool isLoaded() const {
		return m_isLoaded;
	}

	std::string getName() const {
		return name;
	}
	std::string getPath() const {
		return path;
	}

	virtual ~Resource();
};
